package main

import (
	"fmt"
	"runtime"
	"time"
)

var quit chan int = make(chan int)

func loop() {
	for i := 0; i < 10; i++ {
		runtime.Gosched() // 显式地让出CPU时间给其他goroutine
		fmt.Printf("%d ", i)
	}
	quit <- 0
}

func xrange() chan int{ // xrange用来生成自增的整数
	var ch chan int = make(chan int)

	go func() { // 开出一个goroutine
		for i := 0; ; i++ {
			ch <- i  // 直到信道索要数据，才把i添加进信道
		}
	}()

	return ch
}

func foo(i int) chan int {
	c := make(chan int)
	go func () { c <- i }()
	return c
}

func rand01() chan int {
	ch := make(chan int)

	go func () {
		for {
			select { //select会尝试执行各个case, 如果都可以执行，那么随机选一个执行
			case ch <- 0:
			case ch <- 1:
			}
		}
	}()

	return ch
}

func timer(duration time.Duration) chan bool {
	ch := make(chan bool)

	go func() {
		time.Sleep(duration)
		ch <- true // 到时间啦！
	}()

	return ch
}

func main() {
	//messages := make(chan string)
	//go func(message string) {
	//	time.Sleep(time.Second * 2)
	//	messages <- message // 存消息
	//}("Ping!")
	//
	//fmt.Println(<-messages) // 取消息

	//ch := make(chan int)
	//
	//<- ch

	//c, quit := make(chan int), make(chan int)
	//
	//go func() {
	//	c <- 1  // c通道的数据没有被其他goroutine读取走，堵塞当前goroutine
	//	quit <- 0 // quit始终没有办法写入数据
	//}()
	//
	//<- quit // quit 等待数据的写

	//ch := make(chan int)
	//
	//for i := 0; i < 5; i++ {
	//	go func (id int) {
	//		ch <- id
	//	}(i)
	//}
	//
	//for i := 0; i < 5; i++ {
	//	fmt.Print(<- ch)
	//}

	//ch := make(chan int, 3)
	//ch <- 1
	//ch <- 2
	//ch <- 3
	//
	//// 显式地关闭信道
	//close(ch)
	//
	//for v := range ch {
	//	fmt.Println(v)
	//}
	//runtime.GOMAXPROCS(2) // 最多使用2个核
	//
	//go loop()
	//go loop()
	//
	//for i := 0; i < 2; i++ {
	//	<- quit
	//}

	//generator := xrange()
	//
	//for i:=0; i < 1000; i++ {  // 我们生成1000个自增的整数！
	//	fmt.Println(<-generator)
	//}

	//c1, c2, c3 := foo(1), foo(2), foo(3)
	//
	//c := make(chan int)
	//
	//go func() { // 开一个goroutine监视各个信道数据输出并收集数据到信道c
	//	for {
	//		select { // 监视c1, c2, c3的流出，并全部流入信道c
	//		case v1 := <- c1: c <- v1
	//		case v2 := <- c2: c <- v2
	//		case v3 := <- c3: c <- v3
	//		}
	//	}
	//}()
	//
	//// 阻塞主线，取出信道c的数据
	//for i := 0; i < 3; i++ {
	//	fmt.Println(<-c) // 从打印来看我们的数据输出并不是严格的1,2,3顺序
	//}

	//c, quit := make(chan int), make(chan int)
	//
	//go func() {
	//	c <- 2  // 添加数据
	//	quit <- 1 // 发送完成信号
	//} ()
	//
	//for isQuit := false; !isQuit; {
	//	fmt.Println("quit....")
	//	select { // 监视信道c的数据流出
	//	case v := <-c: fmt.Printf("received %d from c", v)
	//	case <-quit: isQuit = true // quit信道有输出，关闭for循环
	//	}
	//	fmt.Println("////")
	//}

	//generator := rand01() //初始化一个01随机生成器
	//
	////测试，打印10个随机01
	//for i := 0; i < 10; i++ {
	//	fmt.Println(<-generator)
	//}

	timeout := timer(time.Second) // 定时1s

	for {
		select {
		case out := <- timeout:
			fmt.Println("already 1s!") // 到时间
			fmt.Println(out)
			return  //结束程序
		}
	}
}
